package com.navinfo.tripanalysis.common.arithmetic;

import com.navinfo.tripanalysis.common.arithmetic.annotation.Arithmetic;
import com.navinfo.tripanalysis.common.arithmetic.common.*;
import com.navinfo.tripanalysis.common.arithmetic.convert.EventDataConvert;
import com.navinfo.tripanalysis.common.arithmetic.custom.VarCruiseControl;
import com.navinfo.tripanalysis.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.tripanalysis.common.arithmetic.enums.EventType;
import com.navinfo.tripanalysis.common.util.ArithmeticUtils;

import java.util.Optional;

/**
 * 定速巡航算法<br/>
 * 依赖里程油耗算法{@link Mileage}<br/>
 * 输出：统计、事件<br/>
 */
public class CruiseControl extends AbstractArithmetic<VarCruiseControl> {
    /**
     * 事件类型
     */
    private static final EventType EVENT_TYPE = EventType.cruise;

    /**
     * 判断当前点是否为定速巡航状态
     */
    public Boolean isCurCruiseControl() {
        return getCommonData().isCruiseControl();
    }

    @Override
    public void calculate() {
        logger.debug("定速巡航算法开始...");
        VarCruiseControl var = super.getObj();
        boolean preStatus = var.isPreCruiseControl();
        boolean curStatus = isCurCruiseControl();
        logger.debug("定速巡航算法，定速巡航状态：上次:{},本次:{}.[terminalId:{}]", preStatus, curStatus, terminalId);

        //算法计算
        switch (getEventStatus(preStatus, curStatus)) {
            case START:
                logger.debug("定速巡航算法，事件开始.[terminalId:{}]", terminalId);
                startEventData(EVENT_TYPE);
                break;
            case IN:
                logger.debug("定速巡航算法，事件中.[terminalId:{}]", terminalId);
                calcEventData(EVENT_TYPE);
                break;
            case END:
                logger.debug("定速巡航算法，事件结束.[terminalId:{}]", terminalId);
                calcEventData(EVENT_TYPE);
                endEventData(var);
                break;
            default :
                logger.debug("定速巡航算法，上一次和本次状态都未开启，跳出算法.");
                break;
        }

        //行程结束时要清理对应的未结束事件
        if (getCommonData().isTripLastNode()) {
            endEventData(var);
        }

        var.setPreCruiseControl(curStatus);
        logger.debug("定速巡航算法结束.[terminalId:{}]", terminalId);
    }

    private void endEventData(VarCruiseControl var){
        endEventData(EVENT_TYPE, eventData -> {
            var.addMileage( Optional.ofNullable(eventData.getExtendField05()).orElse(0.0));
            var.addFuel( Optional.ofNullable(eventData.getExtendField06()).orElse(0.0));
            var.addDuration( Optional.ofNullable(eventData.getDuration()).orElse(0L).intValue());
        });
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarCruiseControl var = super.getObj();
        statisticDataOut.setCruiseMileage(ArithmeticUtils.mileageMToM(var.getMileage()));
        statisticDataOut.setCruiseFuel(ArithmeticUtils.fuelMlToMl(var.getFuel()));
        statisticDataOut.setCruiseDuration(ArithmeticUtils.timeMsToSecond(var.getDuration()));
    }

}
